package com.tju.resource.business.tb_outward;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tju.resource.business.sys.SysParamsService;
import com.tju.resource.business.tb_app_log.TbAppLogService;
import com.tju.resource.business.tb_report_order.TbReportOrderService;
import com.tju.resource.common.ServiceException;
import com.tju.resource.mapper.*;
import com.tju.resource.model.*;
import com.tju.resource.result.Result;
import com.tju.resource.result.ResultEnum;
import com.tju.resource.result.ResultUtil;
import com.tju.resource.tool.tool.EmptyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class TbOutwardServiceImpl implements TbOutwardService {
    @Autowired
    private TbReportOrderService tbReportOrderService;
    @Autowired
    TbOutwardMapper mapper;
    /*外发，物料，订单中间表*/
    @Autowired
    TbOutwardOrderMapper tbOutwardOrderMapper;
    /*外发，耗材，中间表*/
    @Autowired
    TbOutwardConsumablesMapper tbOutwardConsumablesMapper;
    @Autowired
    TbMaterialMapper tbMaterialMapper;
    @Autowired
    TbConsumablesMapper tbConsumablesMapper;
    @Autowired
    TbSendMatlMapper tbSendMatlMapper;
    @Autowired
    SysParamsService paramsService;
    @Autowired
    TbMatlStoreMapper tbMatlStoreMapper;
    @Autowired
    private TbAppLogService tbAppLogService;
    @Autowired
    private TbProcessGroupMapper tbProcessGroupMapper;

    /**
     * 查询外发信息
     *
     * @param params
     * @return
     */
    @Override
    public Result<Object> getAll(@RequestBody Map<String, String> params) {
        try {
            List<TbOutward> list = mapper.retrieveData();
            for (TbOutward outward : list) {
                if (EmptyUtils.isEmpty(outward.getApproveState())) {
                    UpdateWrapper<TbOutward> wrapper = new UpdateWrapper<>();
                    wrapper.eq("id", outward.getId());
                    wrapper.set("approve_state", 2);
                    mapper.update(null, wrapper);
                }
            }
            Page<TbOutward> page = new Page<>(Long.parseLong(params.get("page")), Long.parseLong(params.get("limit")));
            IPage<TbOutward> iPage = mapper.getAll(page, params);
            return ResultUtil.success(ResultEnum.SUCCESS, iPage.getRecords(), iPage.getTotal());
        } catch (Exception e) {
            return ResultUtil.error(ResultEnum.UNKONW_ERROR, e.getMessage());
        }
    }

    /**
     * 添加外发信息
     *
     * @param outward
     * @return
     */
    @Override
    @Transactional
    public Result<Object> add(TbOutward outward) {
        int totalNumber = 0;
        double totalAmount = 0;

        if (outward.getDeliveryTime().getTime() < outward.getOutgoingTime().getTime())
            return ResultUtil.error(ResultEnum.UNKONW_ERROR, "交货日期不能小于外发日期!");
        if (mapper.insert(outward) > 0) {
            if (EmptyUtils.isEmpty(outward.getOutwardOrderList())) {
                throw new ServiceException("请选择订单！");
            }
            for (TbOutwardOrder outwardOrder : outward.getOutwardOrderList()) {
                if (EmptyUtils.isEmpty(outwardOrder.getId()) || EmptyUtils.isEmpty(outwardOrder.getMechanicalId()))
                    throw new ServiceException("请选择订单和物料！");
                if(EmptyUtils.isEmpty(outwardOrder.getOutwardNumber()))
                    throw new ServiceException("请输入外发数");
                if (outwardOrder.getOutwardNumber() > outwardOrder.getSpPcs())
                    throw new ServiceException("外发数量不能大于半成品数量！");
                if (EmptyUtils.isEmpty(outwardOrder.getPrice()))
                    throw new ServiceException("请选择物料单价");
                outwardOrder.setOrderId(outwardOrder.getId());
                outwardOrder.setId(null);
                totalNumber += outwardOrder.getOutwardNumber();
                totalAmount += outwardOrder.getAmount();
                outwardOrder.setOutwardId(outward.getId());
                if (tbOutwardOrderMapper.insert(outwardOrder)==0)
                    throw new ServiceException("外发添加物料失败");
            }
            UpdateWrapper<TbOutward> wrapper = new UpdateWrapper<>();
            wrapper.eq("id", outward.getId());
            wrapper.set("total_number", totalNumber);
            wrapper.set("total_amount", totalAmount);
            if (mapper.update(null, wrapper)==0)
                throw new ServiceException("外发修改金额总数失败");
        }
        return ResultUtil.success(ResultEnum.SUCCESS);
    }


    /**
     * 修改外发信息
     *
     * @param outward
     * @return
     */
    @Override
    @Transactional
    public Result<Object> upd(TbOutward outward) {
        try {
            int totalNumber = 0;
            double totalAmount = 0;
            if (outward.getDeliveryTime().getTime() < outward.getOutgoingTime().getTime())
                return ResultUtil.error(ResultEnum.UNKONW_ERROR, "交货日期不能小于外发日期!");
            if (mapper.updateById(outward) > 0) {
                tbOutwardOrderMapper.delete(new QueryWrapper<TbOutwardOrder>().eq("outward_id", outward.getId()));
                for (TbOutwardOrder outwardOrder : outward.getOutwardOrderList()) {
                    if (EmptyUtils.isEmpty(outwardOrder.getId()) && EmptyUtils.isEmpty(outwardOrder.getMechanicalId())) {
                        throw new ServiceException("请选择订单和物料！");
                    }
                    if (outwardOrder.getOutwardNumber() > outwardOrder.getSpPcs()) {
                        throw new ServiceException("外发数量不能大于半成品数量！");
                    }
                    if (EmptyUtils.isEmpty(outwardOrder.getPrice())) throw new ServiceException("请选择物料单价");
                    outwardOrder.setOrderId(outwardOrder.getId());
                    outwardOrder.setId(null);
                    totalNumber += outwardOrder.getOutwardNumber();
                    totalAmount += outwardOrder.getAmount();
                    outwardOrder.setOutwardId(outward.getId());
                    tbOutwardOrderMapper.insert(outwardOrder);
                }
                UpdateWrapper<TbOutward> wrapper = new UpdateWrapper<>();
                wrapper.eq("id", outward.getId());
                wrapper.set("total_number", totalNumber);
                wrapper.set("total_amount", totalAmount);
                mapper.update(null, wrapper);
                return ResultUtil.success(ResultEnum.SUCCESS);
            }
        } catch (Exception e) {
            throw new ServiceException("修改失败！");
        }
        return ResultUtil.error(ResultEnum.UNKONW_ERROR);
    }

    /**
     * 删除
     *
     * @param oId
     * @return
     */
    @Override
    @Transactional
    public Result<Object> del(Long oId) {
        try {
            if (mapper.deleteById(oId) > 0) {
                tbOutwardOrderMapper.delete(new QueryWrapper<TbOutwardOrder>().eq("outward_id", oId));
                return ResultUtil.success(ResultEnum.SUCCESS);
            } else
                return ResultUtil.error(ResultEnum.UNKONW_ERROR, "删除失败！");
        } catch (Exception e) {
            throw new ServiceException("修改失败！");
        }
    }


    /**
     * 判断供应商需要删除是否外发已使用
     *
     * @param supplierId
     * @return
     */
    @Override
    public Boolean judgmentSupplier(Long supplierId) {
        try {
            QueryWrapper<TbOutward> wrapper = new QueryWrapper<>();
            wrapper.eq("supplier_id", supplierId);
            if (EmptyUtils.isNotEmpty(mapper.selectList(wrapper)))
                return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 外发单添加,修改耗材物品
     *
     * @return
     */
    @Transactional
    @Override
    public Result<Object> managementConsumables(TbOutwardConsumables tbOutwardConsumables) {
        QueryWrapper<TbOutwardConsumables> wrapper = new QueryWrapper<>();
        wrapper.eq("outward_id", tbOutwardConsumables.getOutwardId());
        tbOutwardConsumablesMapper.delete(wrapper);
        if (EmptyUtils.isNotEmpty(tbOutwardConsumables.getConsumablesList()))
            for (TbConsumables consumable : tbOutwardConsumables.getConsumablesList()) {
                if (EmptyUtils.isEmpty(consumable.getUsageAmount()))
                    throw new ServiceException("请输入使用数量！");
                if (consumable.getNumber() < consumable.getUsageAmount())
                    throw new ServiceException("使用数量不能大于仓库总数量！");
                if (tbOutwardConsumablesMapper.insert(new TbOutwardConsumables(tbOutwardConsumables.getOutwardId(), consumable.getId(), consumable.getUsageAmount())) == 0)
                    throw new ServiceException("执行失败！");
            }
        return ResultUtil.success(ResultEnum.SUCCESS, "执行成功！");
    }

    /**
     * 一次审核,二次审核，三次审核
     *
     * @param outward
     * @return
     */
    @Transactional
    @Override
    public Result<Object> oneAudit(TbOutward outward) {
        if(EmptyUtils.isEmpty(outward.getProcessGroupId()))
            return ResultUtil.error(ResultEnum.UNKONW_ERROR, "请选择工艺流程!");
        if (EmptyUtils.isEmpty(tbProcessGroupMapper.selectById(outward.getProcessGroupId())))
            return ResultUtil.error(ResultEnum.UNKONW_ERROR, String.format("工艺流程%s 不存在",outward.getProcessGroupId()));
        UpdateWrapper<TbOutward> outwardUpdateWrapper = new UpdateWrapper<>();
        outwardUpdateWrapper.eq("id", outward.getId());
        if (outward.getApproveState() == 0) {/*一次审核，确认耗材所需数量，通知发料进行审核*/
            if (EmptyUtils.isNotEmpty(outward.getTbOutwardConsumablesList())) {
                for (TbOutwardConsumables consumables : outward.getTbOutwardConsumablesList()) {
                    if (tbSendMatlMapper.insert(new TbSendMatl(outward.getId(), consumables.getTbConsumables().getId(), paramsService.get("MALT__SRC_OW").getRemark(), 1, outward.getReviewer())) == 0)
                        throw new ServiceException("审核失败！");
                }
                outwardUpdateWrapper.set("approve_state", 1);
                int update = mapper.update(null, outwardUpdateWrapper);
                boolean b = tbAppLogService.insertTbAppLog(new TbAppLog(3, outward.getId(), outward.getReviewer(), 1, outward.getNote()));
                if (b && update > 0)
                    return ResultUtil.success(ResultEnum.SUCCESS, "审核成功！");
            } else
                return ResultUtil.error(ResultEnum.UNKONW_ERROR, "请选择外发所需耗材！");
        }
        return ResultUtil.error(ResultEnum.UNKONW_ERROR, "无法审核！");
    }

    @Override
    @Transactional
    public Result<Object> outwardApprove(TbOutward outward) {
        UpdateWrapper<TbOutward> outwardUpdateWrapper = new UpdateWrapper<>();
        outwardUpdateWrapper.eq("id", outward.getId());
        if (outward.getApproveState() == 2) {
            if (EmptyUtils.isNotEmpty(outward.getOutwardOrderList())) {
                for (TbOutwardOrder order : outward.getOutwardOrderList()) {
                    UpdateWrapper<TbMaterial> updateWrapper = new UpdateWrapper<>();
                    updateWrapper.eq("id", order.getMechanicalId());
                    updateWrapper.set("sp_pcs", order.getSpPcs() - order.getOutwardNumber());
                    if (order.getSpPcs() - order.getOutwardNumber() < 0) throw new ServiceException("库存不足");
                    if (tbMaterialMapper.update(null, updateWrapper) == 0)
                        throw new ServiceException("审核失败！");
                }
                outwardUpdateWrapper.set("approve_state", 3);
                int update = mapper.update(null, outwardUpdateWrapper);
                boolean b = tbAppLogService.insertTbAppLog(new TbAppLog(3, outward.getId(), outward.getReviewer(), 1, outward.getNote()));
                if (b && update > 0)
                    return ResultUtil.success(ResultEnum.SUCCESS, "外发成功！");
            }
        } else {
            return ResultUtil.success(ResultEnum.SUCCESS, "审核状态不对");
        }
        return ResultUtil.error(ResultEnum.UNKONW_ERROR, "外发失败！");
    }

    @Override
    @Transactional
    public Result<Object> twoOutwardApprove(TbOutward outward) {
        if (outward.getApproveState() == 3) {
            UpdateWrapper<TbOutward> wrapper = new UpdateWrapper<>();
            wrapper.eq("id", outward.getId());
            wrapper.set("reviewer", outward.getReviewer());
            wrapper.set("audit_time", new Date());
            wrapper.set("approve_state", 4);
            if (mapper.update(null, wrapper) > 0) {
                UpdateWrapper<TbOutwardOrder> updateWrapper = new UpdateWrapper<>();
                for (TbOutwardOrder order : outward.getOutwardOrderList()) {
                    if (order.getQualified() > 0 && EmptyUtils.isNotEmpty(order.getId())) {
                        if (order.getQualified() > order.getOutwardNumber()) {
                            throw new ServiceException("合格数不能大于外发数!");
                        }
                        updateWrapper.clear();
                        updateWrapper.eq("id", order.getOrderId());
                        updateWrapper.set("qualified", order.getQualified());
                        updateWrapper.set("qualified_state", ((order.getOutwardNumber() * order.getScrapRate()) >= order.getQualified()) ? 1 : 0);
                        if (tbOutwardOrderMapper.update(null, updateWrapper) == 0) {
                            throw new ServiceException("审核失败!");
                        }
                        if (EmptyUtils.isEmpty(order.getMechanicalId())) {
                            throw new ServiceException("审核失败!");
                        }
                        if (tbReportOrderService.insertTbReportOrder(new TbReportOrder(order.getMechanicalId(),outward.getId(),outward.getProcessGroupId(),outward.getReviewer(),order.getQualified(),outward.getGroupName())).getCode()!=200) {
                            throw new ServiceException("审核失败!");
                        }
                        /*if (tbMatlStoreMapper.insert(new TbMatlStore(order.getMechanicalId(), Long.valueOf(order.getOutwardNumber()), 1, outward.getReviewer())) == 0) {
                            throw new ServiceException("审核失败!");
                        }*/
                    } else {
                        throw new ServiceException("请输入合格数量!");
                    }
                }
                boolean b = tbAppLogService.insertTbAppLog(new TbAppLog(3, outward.getId(), outward.getReviewer(), 1, outward.getNote()));
                if (b)
                    return ResultUtil.success(ResultEnum.SUCCESS, "审核成功！");
            }
        } else {
            return ResultUtil.success(ResultEnum.SUCCESS, "审核状态不对");
        }
        return ResultUtil.error(ResultEnum.UNKONW_ERROR, "无法审核！");
    }
}
